﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ChatContext;
using System.Net.Sockets;
using System.Threading;
using System.Collections.ObjectModel;
using vxi.chat.library;
using System.Net;
using vxi.com.log;
using System.Windows.Forms;
using System.Collections;
using vxi.com.sync;

namespace vxi.com.server
{

    /// <summary> 
    /// 服务器端业务类 
    /// </summary> 
    public class VxiServer
    {

        #region 自定义变量 & 属性

        private ChatDataContext data;                                         ///< 数据库对象实体

        public bool isRun = false;                                            ///< 服务器启动标识位
        private UdpClient _server;                                            ///< 服务器端消息监听器 
        private Thread _serverThread;                                         ///< 服务器主线程
                                                                             
        private UdpClient _syncserver;                                        ///< 同步服务器端消息监听器 
        private Thread _syncserverThread;                                     ///< 同步服务器主线程  
        private IPEndPoint _syncremotePoint;

        private ObservableCollection<VxiChatSession> _sessionCollections;     ///< 服务器会话池
        private ObservableCollection<VxiUserBase> _userCollections;           ///< 客户端列表

        private delegate void LogFileDelegate(string path, string log, LogType type);
        private LogFileDelegate _logFiledele;

        private delegate void MyDelegate(VxiEvent arg, IPEndPoint _remotePoint);       ///< 定义一个委托
        private MyDelegate Registetdele;                      ///< 注册事件执行委托
        private MyDelegate ChatStartdele;                     ///< 会话开始请求委托
        private MyDelegate ChatStopdele;                      ///< 会话结束请求委托
        private MyDelegate SendMessagedele;                   ///< 聊天事件请求委托
        private MyDelegate UnRegistetdele;                    ///< 注销事件请求委托
        private MyDelegate SetAgentStatusdele;                ///< 改变坐席状态委托
        private MyDelegate SendBinarydele;                    ///< 语音发送请求委托
        private MyDelegate ChatAudioShartdele;                ///< 语音会话开始请求委托
        private MyDelegate ChatAudioShartReplydele;           ///< 语音会话开始应答请求委托                                                      
        private MyDelegate HeartBeatdele;                     ///< 客户端心跳请求委托

        private WriteLogHandle _WriteLogHandle = null;
        private QuantityHandle _QuantityHandleSession = null;
        private QuantityHandle _QuantityHandleUser = null;

        public ObservableCollection<VxiChatSession> SessionCollections
        {
            get { return _sessionCollections; }
            set { _sessionCollections = value; }
        }

        public ObservableCollection<VxiUserBase> UserCollections
        {
            get { return _userCollections; }
            set { _userCollections = value; }
        }

        public QuantityHandle OnQuantitySession
        {
            get { return _QuantityHandleSession; }
            set { _QuantityHandleSession = value; }
        }

        public QuantityHandle OnQuantityUser
        {
            get { return _QuantityHandleUser; }
            set { _QuantityHandleUser = value; }
        }

        public WriteLogHandle OnWriteLog
        {
            get { return _WriteLogHandle; }
            set { _WriteLogHandle = value; }
        }

        #endregion

        #region 委托的方法
        /// <summary>
        /// 显示跟踪记录 
        /// </summary>
        /// <param name="log">记录内容</param>
        /// <param name="type">记录等级</param>
        private void DoWriteLog(string log, LogType type)
        {
            try
            {
                if (_WriteLogHandle != null)
                {
                    string msg = string.Format("[{0}] {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), log);
                    (_WriteLogHandle.Target as System.Windows.Forms.Control).Invoke(_WriteLogHandle, msg, type);
                    _logFiledele.Invoke(Application.StartupPath, msg, type);
                }
            }
            catch (Exception ex)
            {
                _logFiledele.Invoke(Application.StartupPath, ex.Message, LogType.Exception);
            }

        }

        /// <summary>
        /// 显示总会话数量
        /// </summary>
        /// <param name="num"></param>
        private void DoQuantity_Session(int num)
        {
            if (_QuantityHandleSession != null)
            {
                (_QuantityHandleSession.Target as System.Windows.Forms.Control).BeginInvoke(_QuantityHandleSession, num, 0);
            }
        }

        /// <summary>
        /// 显示在线客户端
        /// </summary>
        /// <param name="num1">坐席数</param>
        /// <param name="num2">客户数</param>
        private void DoQuantity_User(int num1, int num2)
        {
            if (_QuantityHandleUser != null)
            {
                (_QuantityHandleUser.Target as System.Windows.Forms.Control).BeginInvoke(_QuantityHandleUser, num1, num2);
            }
        }


        #endregion

        #region 构造器
        /// <summary> 
        /// 构造函数
        /// </summary> 
        public VxiServer()
        {
            data = new ChatDataContext();

            _sessionCollections = new ObservableCollection<VxiChatSession>();
            _userCollections = new ObservableCollection<VxiUserBase>();

            _logFiledele = new LogFileDelegate(VxiLog.RecordWorkingLog);

            Registetdele = new MyDelegate(Registet);
            ChatStartdele = new MyDelegate(ChatStart);
            ChatStopdele = new MyDelegate(ChatStop);
            SendMessagedele = new MyDelegate(SendMessage);
            UnRegistetdele = new MyDelegate(UnRegistet);
            SetAgentStatusdele = new MyDelegate(SetAgentStatus);
            SendBinarydele = new MyDelegate(SendBinary);
            ChatAudioShartdele = new MyDelegate(ChatAudioStart);
            ChatAudioShartReplydele = new MyDelegate(ChatAudioShartReply);
            HeartBeatdele = new MyDelegate(HeartBeat);

            _sessionCollections.CollectionChanged += (s, e) => { DoQuantity_Session(_sessionCollections.Count()); };
            _userCollections.CollectionChanged += (s, e) => { DoQuantity_User(_userCollections.Count(a => a.GetType() == typeof(VxiAgent)), _userCollections.Count(a => a.GetType() == typeof(VxiCustomer))); };

            _serverThread = new Thread(new ThreadStart(Run));

            _syncremotePoint = new IPEndPoint(IPAddress.Any, 0);
            _syncserverThread = new Thread(new ThreadStart(RunSync));
        }

        #endregion


        /// <summary> 
        /// 启动线程 
        /// </summary> 
        public bool Start()
        {
            try
            {
                if (!data.DatabaseExists())
                {
                    DoWriteLog("Database open error.", LogType.Exception);
                    isRun = false;
                    return isRun;
                }
                //主监听线程
                _server = new UdpClient(VxiDefine.SERVER_PORT);
                _serverThread.IsBackground = true;
                _serverThread.Start();

                // 同步线程
                _syncserver = new UdpClient(VxiDefine.SERVER_SYNC_PROT);
                _syncserverThread.IsBackground = true;
                _syncserverThread.Start();

                // 第一次获取主服务器数据
                if (VxiDefine.SERVER_SYNC_NET.Count > 0)
                {
                    Send(new GetData(), VxiDefine.SERVER_SYNC_NET[0]);
                }

                DoWriteLog("The service is started, the listening port: " + VxiDefine.SERVER_PORT.ToString() + ", waiting for the client...", LogType.Event);
                isRun = true;
                return isRun;
            }
            catch (Exception ex)
            {
                DoWriteLog("Start the service error occurs: " + ex.Message, LogType.Exception);
                isRun = false;
                return isRun;
                //throw ex;
            }
        }

        /// <summary> 
        /// 停止线程 
        /// </summary> 
        public void Stop()
        {
            DoWriteLog("Stopping services...", LogType.Event);
            try
            {
                _serverThread.Abort();
                _server.Close();

                _userCollections.Clear();
                _sessionCollections.Clear();

                //停止同步线程
                _syncserverThread.Abort();
                _syncserver.Close();

                DoWriteLog("Service has been stopped!", LogType.Event);

                isRun = false;
            }
            catch (Exception ex)
            {
                DoWriteLog("Stop the service error occurs: " + ex.Message, LogType.Exception);
                //throw ex;
            }
        }

        /// <summary>
        /// 开始扫描
        /// </summary>
        public void Scan()
        {
            try
            {
                ///< 服务器扫描客户端连接状态线程
                Thread _scanThread = new Thread(new ThreadStart(ScanClient));
                _scanThread.Start();
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
            }

        }

        /// <summary>
        /// 扫描客户端状态方法
        /// </summary>
        private void ScanClient()
        {
            return;
            for (int i = 0; i < _userCollections.Count(); i++)
            {
                VxiUserBase user = _userCollections[i];
                if (user.ServerName == VxiDefine.SERVER_NAME)
                {
                    TimeSpan ts1 = new TimeSpan(DateTime.Now.Ticks);
                    TimeSpan ts2 = new TimeSpan(user.LastactionTime.Ticks);
                    TimeSpan ts = ts1.Subtract(ts2).Duration();
                    if (ts.TotalSeconds > 12)
                    {
                        //移除客户端
                        _userCollections.Remove(user);
                        //移除冗余会话
                        DropSession(user);
                    }
                }
            }

        }

        /// <summary>
        /// 删除冗余会话（a 客户端注销; b 客户端异常断线）
        /// </summary>
        /// <param name="user"></param>
        private void DropSession(VxiUserBase user)
        {
            foreach (VxiChatSession session in _sessionCollections)
            {
                if (session.UserCollections.Count(a => a.UserName == user.UserName) > 0)
                {
                    if (session.SeesionMember <= 2)
                    {
                        /// 删除会话
                        _sessionCollections.Remove(session);
                        /// 发送通知消息
                        VxiEvent evt_notify = new VxiEvent(){
                            head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_NOTIFY, _event = VxiDefine.Event.Notify.VXI_EVT_CHAT_SESSION_STATE_CHG }
                        };
                        Hashtable hash_notify = new Hashtable();
                        hash_notify.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_STATUS, VxiDefine.Event.SessionState.VXI_CHAT_SESSION_STATE_NULL);
                        hash_notify.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, session.SessionID);
                        evt_notify.items = hash_notify;
                        foreach (VxiUserBase _user in session.UserCollections)
                            if (_user.UserName != user.UserName)
                            {
                                /// 如果是坐席结束
                                if (user.GetType() == typeof(VxiAgent))
                                {
                                    (user as VxiAgent).State = VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_NOT_READY;
                                }

                                Send(evt_notify, _user.RemotePoint);
                            }
                    }
                }
            }
        }

        /// <summary>
        /// 线程主方法 
        /// </summary>
        private void Run()
        {
            byte[] msgBuffer = null;
            IPEndPoint _remotePoint = new IPEndPoint(IPAddress.Any, 0);
            VxiEvent evt = new VxiEvent();
            while (true)
            {
                try
                {
                    //接受消息 
                    msgBuffer = _server.Receive(ref _remotePoint);
                    //将消息转换为对象 
                    object msgObject = System.Text.Encoding.Default.GetString(msgBuffer);
                    if (msgObject == null) continue;
                    try
                    {
                        evt.loadEvent(msgObject.ToString());
                        switch (evt.head._event)
                        {
                            /// 请求
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_REGISTET_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    Registetdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_START_SESSION_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    ChatStartdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_STOP_SESSION_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    ChatStopdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_SEND_MESSAGE_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    SendMessagedele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_UNREGISTET_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    UnRegistetdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_SET_AGENT_STATE_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    SetAgentStatusdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_SEND_BINARY_REQ:
                                {
                                    SendBinarydele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_START_AUDIO_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    ChatAudioShartdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.Reuqest.VXI_EVT_CHAT_START_AUDIO_REPLY_REQ:
                                {
                                    DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    ChatAudioShartReplydele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            case VxiDefine.Event.HeartBeat.VXI_EVT_CHAT_HEARTBEAT_HEAT:
                                {
                                    //DoWriteLog(VxiGlobals.ToC2SLogFormat(evt, _remotePoint), LogType.General);
                                    HeartBeatdele.Invoke(evt, _remotePoint);
                                    break;
                                }
                            default: break;
                        }
                    }
                    catch (Exception ex)
                    {
                        this.DoWriteLog(ex.Message, LogType.Exception);
                    }
                }
                catch (Exception ex)
                {
                    DoWriteLog(ex.Message, LogType.Exception);
                }
            }
        }

        /// <summary>
        /// 同步线程方法
        /// </summary>
        private void RunSync()
        {
            byte[] msgBuffer = null;

            while (true)
            {
                msgBuffer = _syncserver.Receive(ref _syncremotePoint); //接受消息 
                try
                {
                    //将消息转换为对象 
                    object msgObject = ObjectSerializer.Deserialize(msgBuffer);
                    if (msgObject == null) continue;
                    Type msgType = msgObject.GetType();

                    if (msgType == typeof(AddUser))
                    {
                        _userCollections.Add((msgObject as AddUser).User);
                    }
                    else if (msgType == typeof(DelUser))
                    {
                        VxiUserBase _user = _userCollections.Single(a => a.UserName == (msgObject as DelUser).User.UserName);
                        _userCollections.Remove(_user);
                    }
                    else if (msgType == typeof(UpdateUser))
                    {
                        VxiUserBase _user = _userCollections.Single(a => a.UserName == (msgObject as UpdateUser).User.UserName);
                        _user = (msgObject as UpdateUser).User;
                    }
                    else if (msgType == typeof(AddSession))
                    {
                        _sessionCollections.Add((msgObject as AddSession).Session);
                    }
                    else if (msgType == typeof(DelSession))
                    {
                        VxiChatSession _session = _sessionCollections.Single(a => a.SessionID == (msgObject as DelSession).Session.SessionID);
                        _sessionCollections.Remove(_session);
                    }
                    else if (msgType == typeof(UpdateSession))
                    {
                        VxiChatSession _session = _sessionCollections.Single(a => a.SessionID == (msgObject as UpdateSession).Session.SessionID);
                        _session = (msgObject as UpdateSession).Session;
                    }
                    else if (msgType == typeof(AllData))
                    {
                        foreach (VxiChatSession sess in (msgObject as AllData).SessionList)
                        {
                            _sessionCollections.Add(sess);
                        }
                        foreach (VxiUserBase user in (msgObject as AllData).UserList)
                        {
                            _userCollections.Add(user);
                        }
                    }
                    else if (msgType == typeof(GetData))
                    {
                        Send(new AllData() { SessionList = _sessionCollections, UserList = _userCollections });
                    }

                }
                catch (Exception ex)
                {
                    DoWriteLog(ex.Message, LogType.Exception);
                }
            }
        }


        #region 服务器发包

        /// <summary> 
        /// 服务器发包方法
        /// </summary> 
        public void Send(VxiEvent evt, IPEndPoint remoteIP)
        {
            DoWriteLog(VxiGlobals.ToS2CLogFormat(evt, remoteIP), LogType.General);
            if (evt == null) return;
            byte[] buffer = System.Text.Encoding.Default.GetBytes(evt.toString());
            _server.Send(buffer, buffer.Length, remoteIP);
        }

        /// <summary> 
        /// 服务器发同步包方法(无日志)
        /// </summary> 
        public void Send(MessageBase msg)
        {
            if (msg == null) return;
            foreach (IPEndPoint ipp in VxiDefine.SERVER_SYNC_NET)
            {
                Send(msg, ipp);
            }
        }

        /// <summary>
        /// 重载服务器发同步包方法(无日志) 
        /// </summary>
        /// <param name="msg"></param>
        public void Send(MessageBase msg, IPEndPoint remoteIP)
        {
            if (msg == null) return;
            byte[] buffer = ObjectSerializer.Serialize(msg);
            _server.Send(buffer, buffer.Length, remoteIP);

        }

        /// <summary>
        /// 服务器发包方法(无日志)
        /// </summary>
        /// <param name="evt"></param>
        /// <param name="remoteIP"></param>
        public void SendNoLog(VxiEvent evt, IPEndPoint remoteIP)
        {
            if (evt == null) return;
            byte[] buffer = System.Text.Encoding.Default.GetBytes(evt.toString());
            _server.Send(buffer, buffer.Length, remoteIP);
        }

        #endregion

        #region 事件处理
        /// <summary>
        /// 用户注册处理
        /// </summary>
        /// <param name="evt"></param>
        private void Registet(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_REGISTET_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                switch (int.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER_TYPE].ToString()))
                {
                    case VxiDefine.Event.UserType.VXI_CHAT_USER_TYPE_AGENT:
                        {
                            VxiAgent agt = new VxiAgent();
                            agt.ServerName = VxiDefine.SERVER_NAME;
                            agt.UserName = evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString();
                            agt.RemotePoint = _remotePoint;
                            agt.State = VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_READY;
                            agt.LocalPoint = new IPEndPoint(IPAddress.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_IPADDR].ToString()), int.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_UDP_PORT].ToString()));
                            if (_userCollections != null && _userCollections.Where(a => a.UserName == agt.UserName).Count() <= 0)
                            {
                                _userCollections.Add(agt);

                                //同步
                                Send(new AddUser() { User = agt });
                            }

                            ///日志信息
                            DoWriteLog("Agent: " + agt.UserName + " Login.", LogType.Event);
                            ///发送确认消息
                            hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                            evt_echo.items = hash_echo;
                            Send(evt_echo, _remotePoint);
                            break;
                        }
                    case VxiDefine.Event.UserType.VXI_CHAT_USER_TYPE_CUSTOMER:
                        {
                            VxiCustomer cus = new VxiCustomer();
                            cus.ServerName = VxiDefine.SERVER_NAME;
                            cus.UserName = evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString();
                            cus.RemotePoint = _remotePoint;
                            cus.LocalPoint = new IPEndPoint(IPAddress.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_IPADDR].ToString()), int.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_UDP_PORT].ToString()));
                            if (_userCollections != null && _userCollections.Where(a => a.UserName == cus.UserName).Count() <= 0)
                            {
                                _userCollections.Add(cus);

                                //同步
                                Send(new AddUser() { User = cus });
                            }
                            ///日志信息
                            DoWriteLog("Customer: " + cus.UserName + " Login.", LogType.Event);
                            ///发送确认消息
                            hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                            evt_echo.items = hash_echo;
                            Send(evt_echo, _remotePoint);
                            break;
                        }
                    case VxiDefine.Event.UserType.VXI_CHAT_USER_TYPE_SUPERVISOR:
                        break;
                    case VxiDefine.Event.UserType.VXI_CHAT_USER_TYPE_NULL:
                        break;
                    default: break;
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                ///发送异常通知消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 用户注销处理
        /// </summary>
        /// <param name="evt"></param>
        private void UnRegistet(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_UNREGISTET_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                if (_userCollections != null && _userCollections.Count(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString()) >= 1)
                {
                    ///移除客户端
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    _userCollections.Remove(user);

                    //同步
                    Send(new DelUser() { User = user });

                    ///日志信息
                    if (user.GetType() == typeof(VxiAgent))
                    {
                        DoWriteLog("Agent: " + evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString() + " Logout.", LogType.Event);
                    }
                    else if (user.GetType() == typeof(VxiCustomer))
                    {
                        DoWriteLog("Customer: " + evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString() + " Logout.", LogType.Event);
                    }

                    ///发送成功确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    ///其他相关冗余会话
                    DropSession(user);
                }
                else
                {
                    ///发送失败确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "The client is not on line!");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }

            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);

                ///发送异常确认消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 建立会话请求处理
        /// </summary>
        /// <param name="evt"></param>
        private void ChatStart(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_START_SESSION_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {

                if (_userCollections.OfType<VxiAgent>().Cast<VxiAgent>().Where(a => a.State == VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_READY).Count() > 0)
                {
                    /// 新建一个会话
                    VxiChatSession session = new VxiChatSession();

                    /// 坐席分配规则未写,默认第一个READY的坐席
                    VxiAgent age = _userCollections.OfType<VxiAgent>().Cast<VxiAgent>().FirstOrDefault(a => a.State == VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_READY);
                    VxiCustomer cus = _userCollections.OfType<VxiCustomer>().Cast<VxiCustomer>().SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());

                    /// 更新客户端最后响应时间
                    cus.UpdateLastTime();

                    session.UserCollections.Add(cus);
                    session.UserCollections.Add(age);
                    _sessionCollections.Add(session);

                    //同步
                    Send(new AddSession() { Session = session });

                    /// 置该坐席为忙
                    age.State = VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_BUSY;

                    //同步
                    Send(new UpdateUser() { User = age });

                    /// 发送确认给客户
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, session.SessionID);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    /// 发送通知给坐席
                    evt_echo = new VxiEvent()
                    {
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_NOTIFY, _event = VxiDefine.Event.Notify.VXI_EVT_CHAT_SESSION_STATE_CHG }
                    };
                    hash_echo = new Hashtable();
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_STATUS, VxiDefine.Event.SessionState.VXI_CHAT_SESSION_STATE_TALKING);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, session.SessionID);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, age.RemotePoint);

                    DoWriteLog(string.Format("Session: {0} start.", session.SessionID), LogType.Event);
                }
                else
                {
                    ///发送坐席无空闲通知消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "All of Agents  Busy！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);

                ///发送异常确认消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
            }
        }

        /// <summary>
        /// 结束会话请求处理
        /// </summary>
        /// <param name="evt"></param>
        private void ChatStop(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_STOP_SESSION_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                VxiChatSession session = _sessionCollections.SingleOrDefault(a => a.SessionID == Int32.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString()));
                if (session != null)
                {
                    /// 删除会话
                    _sessionCollections.Remove(session);

                    //同步
                    Send(new DelSession() { Session = session });

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();

                    /// 如果是坐席请求结束
                    if (user.GetType() == typeof(VxiAgent))
                    {
                        (user as VxiAgent).State = VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_NOT_READY;

                        //同步
                        Send(new UpdateUser() { User = user });
                    }

                    /// 发送确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    /// 发送通知消息（to:会话中所有其他客户端)
                    VxiEvent evt_notify = new VxiEvent(){
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_NOTIFY, _event = VxiDefine.Event.Notify.VXI_EVT_CHAT_SESSION_STATE_CHG }
                    };
                    Hashtable hash_notify = new Hashtable();
                    hash_notify.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_STATUS, VxiDefine.Event.SessionState.VXI_CHAT_SESSION_STATE_NULL);
                    hash_notify.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, session.SessionID);
                    evt_notify.items = hash_notify;
                    foreach (VxiUserBase _user in session.UserCollections)
                        if (_user.UserName != evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString())
                        {
                            /// 如果是坐席
                            if (user.GetType() == typeof(VxiAgent))
                            {
                                (user as VxiAgent).State = VxiDefine.Event.AgentState.VXI_CHAT_AGENT_STATE_NOT_READY;

                                //同步
                                Send(new UpdateUser() { User = _user });
                            }

                            Send(evt_notify, _user.RemotePoint);
                        }
                    /// 事件日志
                    DoWriteLog(string.Format("Session: {0} stop.", session.SessionID), LogType.Event);
                }
                else
                {
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "Session is not exist！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);

                ///发送异常确认消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 发送聊天消息
        /// </summary>
        /// <param name="evt"></param>
        private void SendMessage(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_SEND_MESSAGE_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                VxiChatSession session = _sessionCollections.SingleOrDefault(a => a.SessionID == Int32.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString()));
                if (session != null)
                {
                    /// 发送确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();


                    /// 发送转发消息
                    VxiEvent evt_req = new VxiEvent()
                    {
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_REQUEST, _event = VxiDefine.Event.Reuqest.VXI_EVT_CHAT_SEND_MESSAGE_REQ }
                    };
                    Hashtable hash_req = new Hashtable();
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_USER, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_TEXT, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_TEXT].ToString());
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString());
                    evt_req.items = hash_req;
                    foreach (VxiUserBase _user in session.UserCollections)
                        if (_user.UserName != evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString())
                            Send(evt_req, _user.RemotePoint);
                }
                else
                {
                    /// 发送失败消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "Session is not exist！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }

            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                ///发送异常通知消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 发送语音消息
        /// </summary>
        /// <param name="evt"></param>
        private void SendBinary(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_SEND_BINARY_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                VxiChatSession session = _sessionCollections.SingleOrDefault(a => a.SessionID == Int32.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString()));
                if (session != null)
                {
                    /// 发送确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    SendNoLog(evt_echo, _remotePoint);

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();

                    /// 发送转发消息
                    VxiEvent evt_req = new VxiEvent()
                    {
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_REQUEST, _event = VxiDefine.Event.Reuqest.VXI_EVT_CHAT_SEND_BINARY_REQ }
                    };
                    Hashtable hash_req = new Hashtable();
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_USER, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CONTENT, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_CONTENT].ToString());
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString());
                    evt_req.items = hash_req;
                    foreach (VxiUserBase _user in session.UserCollections)
                        if (_user.UserName != evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString())
                            SendNoLog(evt_req, _user.RemotePoint);
                }
                else
                {
                    /// 发送失败消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "Session is not exist！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                ///发送异常通知消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 建立语音会话请求处理
        /// </summary>
        /// <param name="evt"></param>
        /// <param name="_remotePoint"></param>
        private void ChatAudioStart(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_START_AUDIO_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                VxiChatSession session = _sessionCollections.SingleOrDefault(a => a.SessionID == Int32.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString()));
                if (session != null)
                {
                    /// 发送确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();

                    /// 发送建立语音会话请求消息
                    VxiEvent evt_req = new VxiEvent()
                    {
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_REQUEST, _event = VxiDefine.Event.Reuqest.VXI_EVT_CHAT_START_AUDIO_REQ }
                    };
                    Hashtable hash_req = new Hashtable();
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_USER, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString());
                    evt_req.items = hash_req;
                    foreach (VxiUserBase _user in session.UserCollections)
                        if (_user.UserName != evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString())
                            Send(evt_req, _user.RemotePoint);
                }
                else
                {
                    /// 发送失败消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "Session is not exist！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                ///发送异常通知消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 语音会话应答请求消息
        /// </summary>
        /// <param name="evt"></param>
        /// <param name="_remotePoint"></param>
        private void ChatAudioShartReply(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_START_AUDIO_REPLY_ECHO }
            };
            Hashtable hash_echo = new Hashtable();
            try
            {
                VxiChatSession session = _sessionCollections.SingleOrDefault(a => a.SessionID == Int32.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString()));
                if (session != null)
                {
                    /// 发送确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();

                    /// 发送通知给其他客户端
                    VxiEvent evt_req = new VxiEvent()
                    {
                        head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_NOTIFY, _event = VxiDefine.Event.Notify.VXI_EVT_CHAT_AUDIO_STATE_CHG }
                    };
                    Hashtable hash_req = new Hashtable();

                    if (evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT].ToString() == VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK)
                        hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_STATUS, VxiDefine.Event.ChatAudioState.VXI_CHAT_AUDIO_STATE_START);
                    else
                        hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_STATUS, VxiDefine.Event.ChatAudioState.VXI_CHAT_AUDIO_STATE_NULL);

                    hash_req.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID, evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_SESSION_ID].ToString());
                    evt_req.items = hash_req;
                    foreach (VxiUserBase _user in session.UserCollections)
                        if (_user.UserName != evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString())
                            Send(evt_req, _user.RemotePoint);
                }
                else
                {
                    /// 发送失败消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "Session is not exist！");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                ///发送异常通知消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);
            }
        }

        /// <summary>
        /// 设置坐席状态
        /// </summary>
        /// <param name="evt"></param>
        private void SetAgentStatus(VxiEvent evt, IPEndPoint _remotePoint)
        {
            VxiEvent evt_echo = new VxiEvent()
            {
                head = new VxiEvent.Head() { _domain = VxiDefine.Event.Domain.VXI_EVT_DOMAIN_CHAT, _type = VxiDefine.Event.Type.VXI_EVT_TYPE_ECHO, _event = VxiDefine.Event.Echo.VXI_EVT_CHAT_SET_AGENT_STATE_ECHO }
            };
            Hashtable hash_echo = new Hashtable();

            try
            {
                VxiAgent agent = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString()) as VxiAgent;
                if (agent != null)
                {
                    /// 发送成功确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_OK);
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                    agent.State = int.Parse(evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_AGENT_STATE].ToString());

                    /// 更新客户端最后响应时间
                    VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                    user.UpdateLastTime();

                }
                else
                {
                    /// 发送失败确认消息
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                    hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, "The agent is not online!");
                    evt_echo.items = hash_echo;
                    Send(evt_echo, _remotePoint);
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
                /// 发送异常消息
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_RESULT, VxiDefine.Event.ResultType.VXI_EVT_ITEM_RESP_FAIL);
                hash_echo.Add(VxiDefine.Event.Item.VXI_EVT_ITEM_CAUSE, ex.Message);
                evt_echo.items = hash_echo;
                Send(evt_echo, _remotePoint);

            }
        }

        /// <summary>
        /// 心跳事件请求
        /// </summary>
        private void HeartBeat(VxiEvent evt, IPEndPoint _remotePoint)
        {
            try
            {
                VxiUserBase user = _userCollections.SingleOrDefault(a => a.UserName == evt.items[VxiDefine.Event.Item.VXI_EVT_ITEM_USER].ToString());
                if (user != null)
                {
                    user.UpdateLastTime();
                }
            }
            catch (Exception ex)
            {
                DoWriteLog(ex.Message, LogType.Exception);
            }
        }


        #endregion
    }
}
